﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
using HTTT.DTO;
using HTTT.DataAccess;
using HTTT.Utilities;

namespace HTTT.AD
{
    public class ADManager
    {
        #region Private
        private string LDAPPath;
        private string LDAPUser;
        private string LDAPPassword;
        private string LDAPDomain;
        private OU _ou;
        private Groups _groups;
        private Users _user;


        /// <summary>
        /// Get direcory
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public DirectoryEntry GetDirectoryEntry(string path)
        {
            return new DirectoryEntry(path, LDAPUser, LDAPPassword, AuthenticationTypes.Secure);
        }
        /// <summary>
        /// Get root directory
        /// </summary>
        /// <returns></returns>
        public DirectoryEntry GetSearchRoot()
        {
            return new DirectoryEntry(LDAPPath, LDAPUser, LDAPPassword, AuthenticationTypes.Secure);
        }
        #endregion

        #region Constructor
        public ADManager(string ldapDomain, string ldapPath, string ldapUser, string ldapPwd)
        {
            LDAPDomain = ldapDomain;
            LDAPPath = ldapPath;
            LDAPUser = ldapUser;
            LDAPPassword = ldapPwd;
            
            //Fix data
            // For 31 - test
            //LDAPDomain = "vinhphucdev.gov.vn";
            //LDAPPath = "LDAP://10.20.27.31";
            //LDAPUser = "vinhphucdev\\administrator";
            //LDAPPassword = "vpd#123!@#";

            //ForAD
            //LDAPDomain = "vinhphuc.vn";
            //LDAPPath = "LDAP://10.20.11.11";
            //LDAPUser = "vinhphuc\administrator";
            //LDAPPassword = "vph@123$$";



            _ou = new OU(LDAPUser, LDAPPassword);
            _groups = new Groups(LDAPUser, LDAPPassword);
            _user = new Users(LDAPUser, LDAPPassword);
        }
        #endregion

        #region Public
        /// <summary>
        /// Get OU by path
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public List<OUDTO> GetOUListByPath(String path)
        {
            return _ou.GetOUListByPath(GetDirectoryEntry(path));
        }

        /// <summary>
        /// Get Ou of domain
        /// </summary>
        /// <returns></returns>
        public List<OUDTO> GetOUAllList()
        {
            return _ou.GetOUListByPath(GetSearchRoot());
        }

        /// <summary>
        /// Get Group by path
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public List<GroupsDTO> GetGroupListByPath(String ouPath)
        {
            List<GroupsDTO> ResultList = new List<GroupsDTO>();
            return _groups.GetAllGroupsInPath(LDAPDomain, ouPath);
        }

        /// <summary>
        /// Get all user in OU
        /// </summary>
        /// <param name="OUPath"></param>
        /// <returns></returns>
        public List<HT_User> GetUserInOU(string OUPath)
        {
            IEnumerable<HT_User> DataList = _user.GetUserInOU(LDAPDomain, OUPath);
            if (DataList != null)
            {
                return DataList.ToList();
            }
            return null;
        }
        #endregion

        /// <summary>
        /// Add new user
        /// </summary>
        /// <param name="adduser"></param>
        /// <returns></returns>
        public ReturnValue<bool> AddUserPrincipalByHT_User(HT_User adduser)
        {
            
            string ouPath = adduser.distinguishedName;
            ouPath = ouPath.Substring(ouPath.IndexOf(',') + 1);

            return _user.AddUserPrincipalByHT_User(adduser, LDAPDomain, ouPath , HTTT.Utilities.Constants.DEFAULT_PWD , true);
        }

        /// <summary>
        /// Edit user
        /// </summary>
        /// <param name="adduser"></param>
        /// <returns></returns>
        public ReturnValue<bool> UpdateUserPrincipalByHT_User(HT_User editUser)
        {
            return _user.UpdateUserPrincipalByHT_User(editUser, LDAPDomain);
        }

        /// <summary>
        /// Reset user password
        /// </summary>
        /// <param name="resetuser"></param>
        /// <param name="newPassword"></param>
        /// <returns></returns>
        public ReturnValue<bool> ResetUserPrincipalByHT_User(string username, string newPassword)
        {
            return _user.ResetPwd(username, newPassword);
        }

        /// <summary>
        /// Delete user
        /// </summary>
        /// <param name="resetuser"></param>
        /// <param name="newPassword"></param>
        /// <returns></returns>
        public ReturnValue<bool> DeleteUserPrincipalByHT_User(string username)
        {
            return _user.DeleteUser(username);
        }

        public ReturnValue<bool> SetBlockUserPrincipal(string username, bool status)
        {
            return _user.SetEnable(username, status);
        }

        public ReturnValue<bool> UpdateGroupPrincipalByHT_Groups(HT_Groups updateGroup)
        {
            return _groups.UpdateGroupPrincipalByHT_Groups(updateGroup, LDAPDomain);
        }

        public ReturnValue<bool> AddGroupPrincipalByHT_Groups(HT_Groups addGroup)
        {
            string ouPath = addGroup.LDAPPath;
            ouPath = ouPath.Substring(ouPath.IndexOf(',') + 1);

            return _groups.CreateNewGroup(addGroup, LDAPDomain, ouPath);
        }

        public ReturnValue<bool> DeleteGroupPrincipalBy(string groupName, string domain)
        {
            return _groups.DeleteGroup(groupName, domain);
        }

        
        public ReturnValue<bool> AddUserToGroup(string groupName, string username)
        {
            return _groups.AddUserToGroup(username, LDAPDomain, groupName);
        }

        public ReturnValue<bool> RemoveUserFromGroup(string groupName, string username)
        {
            return _groups.RemoveUserFromGroup(username, LDAPDomain, groupName);
        }

        public ReturnValue<bool> AddNewOU(HT_OU addOU)
        {
            string ouPath = addOU.DistinguishedName;
            ouPath = ouPath.Substring(ouPath.IndexOf(',') + 1);

            return _ou.CreateNewOU(addOU.Name, LDAPDomain, ouPath);
        }

        public ReturnValue<bool> RenameOU(string newName, HT_OU OldEditOU)
        {
            return _ou.RenameOU(newName, OldEditOU, LDAPDomain);
        }

        public ReturnValue<bool> MoveOU(string newParentPath, HT_OU OldEditOU)
        {
            return _ou.MoveOU(newParentPath, OldEditOU, LDAPDomain);
        }

        public ReturnValue<bool> DeleteOU(string ouPath)
        {
            return _ou.DeleteOU(LDAPDomain, ouPath);
        }

        public List<HT_UserLoginCount> GetLoginCount4AllUser()
        {
            return _user.GetLoginCount4AllUser(LDAPDomain, LDAPPath);
        }
    }
}
